package com.uwlaser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.domain.CraftOperation;
import com.uwlaser.service.mapper.CraftOperationMapper;
import com.uwlaser.utils.FileUtil;
import lombok.AllArgsConstructor;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.utils.ConvertUtil;
import com.uwlaser.utils.PageUtil;
import com.uwlaser.domain.DataPassStation;
import com.uwlaser.service.DataPassStationService;
import com.uwlaser.service.dto.DataPassStationDto;
import com.uwlaser.service.dto.DataPassStationQueryParam;
import com.uwlaser.service.mapper.DataPassStationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = DataPassStationService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataPassStationServiceImpl extends CommonServiceImpl<DataPassStationMapper, DataPassStation> implements DataPassStationService {

    // private final RedisUtils redisUtils;
    private final DataPassStationMapper dataPassStationMapper;

    private final CraftOperationMapper craftOperationMapper;
    @Override
    public PageInfo<DataPassStationDto> queryAll(DataPassStationQueryParam query, Pageable pageable) {
        IPage<DataPassStation> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<DataPassStation> page = dataPassStationMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, DataPassStationDto.class);
    }

    @Override
    public List<DataPassStationDto> queryAll(DataPassStationQueryParam query){
        return ConvertUtil.convertList(dataPassStationMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), DataPassStationDto.class);
    }

    @Override
    public DataPassStation getById(Integer id) {
        return dataPassStationMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public DataPassStationDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), DataPassStationDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DataPassStationDto resources) {
        DataPassStation entity = ConvertUtil.convert(resources, DataPassStation.class);
        return dataPassStationMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(DataPassStationDto resources){
        DataPassStation entity = ConvertUtil.convert(resources, DataPassStation.class);
        int ret = dataPassStationMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<Integer> ids){
        // delCaches(ids);
        return dataPassStationMapper.deleteBatchIds(ids);
    }

    @Override
    public Map<String, Object> getEquipmentMeter(DataPassStationQueryParam query) throws ParseException {
        DecimalFormat df = new DecimalFormat("0.00");
        Map<String, Object> map = new HashMap<>();
        //工序编码
        List<String> codeProcedure = new ArrayList<>();
        if (CollectionUtils.isEmpty(query.getCreateTime())) {
            List<Date> createTime = new ArrayList<>();
            createTime.add(getStartTime());
            createTime.add(getEndTime());
            query.setCreateTime(createTime);
        }
        //获取工序信息
        List<CraftOperation> craftOperations = craftOperationMapper.selectList(null);
        List<DataPassStation> dataPassStations = dataPassStationMapper.selectList(new LambdaQueryWrapper<DataPassStation>()
                .select(DataPassStation::getResult, DataPassStation::getOperationCode, DataPassStation::getEntryTime, DataPassStation::getExitTime)
                .ge(DataPassStation::getCreateTime, query.getCreateTime().get(0)).le(DataPassStation::getCreateTime, query.getCreateTime().get(1))
                .isNotNull(DataPassStation::getExitTime));
        //节拍
        List<String> meters = new ArrayList<>();
        //分组
        if (!CollectionUtils.isEmpty(dataPassStations)) {
            Map<String, List<DataPassStation>> collect = dataPassStations.stream().collect(Collectors.groupingBy(e -> e.getOperationCode()));
            //获取各工位节拍
            for (String s : collect.keySet()) {
                codeProcedure.add(craftOperations.stream().filter(g -> g.getOperationCode()
                        .equals(s)).collect(Collectors.toList()).get(0).getOperationName());
                //计算平均节拍
                meters.add(df.format(calculateMeter(collect.get(s))));
            }
        }
        map.put("xAxis", codeProcedure);
        map.put("data", meters);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Integer id){
        Set<Integer> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/

    @Override
    public void download(List<DataPassStationDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (DataPassStationDto dataPassStation : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("产品SN", dataPassStation.getProductSn());
              map.put("产品型号", dataPassStation.getProductCode());
              map.put("产品类型", dataPassStation.getProductType());
              map.put("订单编号", dataPassStation.getOrderCode());
              map.put("工单编号", dataPassStation.getWorkOrderCode());
              map.put("结果", dataPassStation.getResult());
              map.put("产线编号", dataPassStation.getLienCode());
              map.put("工段编号", dataPassStation.getSectionCode());
              map.put("工位编号", dataPassStation.getStationCode());
              map.put("工序编号", dataPassStation.getOperationCode());
              map.put("设备编号", dataPassStation.getDeviceCode());
              map.put("通道编码", dataPassStation.getAisleCode());
              map.put("托盘编码", dataPassStation.getTrayCode());
              map.put("进站时间", dataPassStation.getEntryTime());
              map.put("出站时间", dataPassStation.getExitTime());
              map.put("加工模式", dataPassStation.getProcessedMode());
              map.put("返修次数", dataPassStation.getRepairNum());
              map.put("创建人", dataPassStation.getCreateBy());
              map.put("创建时间", dataPassStation.getCreateTime());
              map.put("更新人", dataPassStation.getUpdateBy());
              map.put("更新时间", dataPassStation.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }

    /**
     * 计算节拍
     */
    public Double calculateMeter(List<DataPassStation> dataPassStations) {
        Double num = 0.0;
        for (DataPassStation dataPassStation : dataPassStations) {
            //进站时间
            Date entryTime = dataPassStation.getEntryTime();
            //出站时间
            Date exitTime = dataPassStation.getExitTime();
            num += ((exitTime.getTime() - entryTime.getTime()) / 1000);
        }
        return num / dataPassStations.size();
    }

    private static Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    private static Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    @Override
    public DataPassStation getPassStation(DataPassStation dataPassStation) {
        return dataPassStationMapper.getPassStation(dataPassStation);
    }
}
